package cn.jesin.ssmss01.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.jesin.ssmss01.common.DefaultPassword;
import cn.jesin.ssmss01.common.LoginType;
import cn.jesin.ssmss01.common.OthType;
import cn.jesin.ssmss01.common.RedisKeyFlag;
import cn.jesin.ssmss01.entity.OtherAuth;
import cn.jesin.ssmss01.entity.User;
import cn.jesin.ssmss01.mapper.OtherAuthMapper;
import cn.jesin.ssmss01.mapper.UserMapper;
import cn.jesin.ssmss01.vo.JwtUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 谷汉斌
 * @description 实现类实现UserDetasService接口，
 * 用于对 登录用户 进行验证以及权限获取 实现自定义登录验证
 * @createTime 2024/7/22 下午8:15
 */
@Slf4j
@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private OtherAuthMapper otherAuthMapper;

    @Autowired
    RedisTemplate<String, String> redisTemplate;

    /**
     * 自定义登录验证
     *
     * @param key 由用户唯一标识和登录方式组成
     * @return 封装的用户信息
     */
    @Override
    public UserDetails loadUserByUsername(String key) throws UsernameNotFoundException {
        //设置错误密码
        String errorPassword = new BCryptPasswordEncoder().encode(new Date() + "用户没设置还想密码登录，只能设置失败");
        //提取用户验证唯一标识和验证类型
        String[] split = key.split(":");
        log.info("验证的用户信息【用户唯一标识：{}，授权平台：{}，登录方式：{}】，", split[0], split[1], split[2]);
        //判断登录方式(如果是手机验证码登录)
        if (split[2].equals(LoginType.VERIFICATION_CODE_LOGIN.getType())) {
            String phoneNumber = split[0];
            //从redis获取验证码
            String code = redisTemplate.opsForValue().get(phoneNumber + RedisKeyFlag.PHONE_CODE);
            if (StrUtil.isNotBlank(code)) {
                return new JwtUser(key, code, AuthorityUtils.commaSeparatedStringToAuthorityList("user"));
            }
            //如果是密码登录
        } else if (split[2].equals(LoginType.PASSWORD_LOGIN.getType())) {
            //如果是账号+密码登录
            if (OthType.USERNAME.getType().equals(split[1])) {
                //从数据库获取用户信息
                Map<String, Object> map = new HashMap<>(1);
                map.put(split[1], split[0]);
                User user = userMapper.selectUserByKey(map);
                if (null == user) {
                    return new JwtUser(null, errorPassword, null);
                }
                if (DefaultPassword.PASSWORD.equals(user.getPassword()) || StrUtil.isBlank(user.getPassword())) {
                    return new JwtUser(null, errorPassword, null);
                }
                log.info("用户名： {} 存在", user.getUsername());
                //获取用户角色，便于设置权限
                String role = user.getRole();
                //封装用户信息，并返回
                return new JwtUser(key, user.getPassword(), AuthorityUtils.commaSeparatedStringToAuthorityList(role));
            }
            //如果是手机号加密码登录
            if (OthType.PHONE.getType().equals(split[1])) {
                //从数第三方授权表中获取用户信息
                OtherAuth otherAuth = otherAuthMapper.selectOtherAuthByoAuthTypeAndoAuthId(split[1], split[0]);
                if (null != otherAuth) {
                    log.info("手机号：{} 存在", otherAuth.getOAuthId());
                    //获取用户角色，便于设置权限
                    User user = userMapper.selectUserByKey(new HashMap<>(1) {{
                        put("username", otherAuth.getUsername());
                    }});
                    if (null == user) {
                        return new JwtUser(null, errorPassword, null);
                    }
                    if (DefaultPassword.PASSWORD.equals(user.getPassword()) || StrUtil.isBlank(user.getPassword())) {
                        return new JwtUser(null, errorPassword, null);
                    }
                    String role = user.getRole();
                    //封装用户信息，并返回
                    return new JwtUser(key, user.getPassword(), AuthorityUtils.commaSeparatedStringToAuthorityList(role));
                }
            }
            //如果是邮箱+密码登录
            if (OthType.EMAIL.getType().equals(split[1])) {
                //从数第三方授权表中获取用户信息
                OtherAuth otherAuth = otherAuthMapper.selectOtherAuthByoAuthTypeAndoAuthId(split[1], split[0]);
                if (null != otherAuth) {
                    log.info("邮箱：{} 存在", otherAuth.getOAuthId());
                    //获取用户角色，便于设置权限
                    User user = userMapper.selectUserByKey(new HashMap<>(1) {{
                        put("username", otherAuth.getUsername());
                    }});
                    if (null == user) {
                        return new JwtUser(null, errorPassword, null);
                    }
                    if (DefaultPassword.PASSWORD.equals(user.getPassword()) || StrUtil.isBlank(user.getPassword())) {
                        return new JwtUser(null, errorPassword, null);
                    }
                    String role = user.getRole();
                    //封装用户信息，并返回
                    return new JwtUser(key, user.getPassword(), AuthorityUtils.commaSeparatedStringToAuthorityList(role));
                }
            }
        }
        return new JwtUser(null, errorPassword, null);
    }
}